package tt.dz.biz.service.account;

import java.math.BigDecimal;
import java.util.List;
import org.springframework.util.CollectionUtils;
import tt.dz.biz.dao.account.AccountingDAO;
import tt.dz.common.BigDecimalUtil;
import tt.dz.common.BusinessException;
import tt.dz.common.DzConstants;
import tt.dz.common.DzConstants.balType;
import tt.dz.common.DzConstants.borrowOrLoanFlag;
import tt.dz.common.DzConstants.receiveOrPay;
import tt.dz.common.DzConstants.subjectType;
import tt.dz.common.LogUtil;
import tt.dz.vo.AccountingRuleVO;
import tt.dz.vo.MerchAccountDividendVO;
import tt.dz.vo.MerchantSubjectAccVO;
import tt.dz.vo.OfflineAccountDetailVO;
import tt.dz.vo.SubjectVO;
import tt.dz.vo.TranInfoVO;
import tt.dz.vo.TranSubVO;

public class MerchantToOfflineCardPOJO
  extends AccountDividendPOJO
{
  private OfflineAccountDetailVO offlineAccountDetail;
  private String cardNo;
  
  public MerchantToOfflineCardPOJO() {}
  
  public MerchantToOfflineCardPOJO(TranInfoVO tranInfoVO)
    throws Exception
  {
    super(tranInfoVO);
    init();
  }
  
  public MerchantToOfflineCardPOJO init()
    throws Exception
  {
    try
    {
      this.platMerchantCode = this.tranInfoVO.getOriginalPayer();
      if (null != this.tranInfoVO.getReceiver()) {
        this.cardNo = this.tranInfoVO.getReceiver();
      } else {
        this.cardNo = ((TranSubVO)this.tranInfoVO.getTranSubVOList().get(0)).getReceiver();
      }
    }
    catch (Exception e)
    {
      LogUtil.error("初始化交易记录失败", e);
      throw e;
    }
    return this;
  }
  
  private MerchantToOfflineCardPOJO addTotalaccount()
    throws Exception
  {
    try
    {
      MerchAccountDividendVO dividend = new MerchAccountDividendVO();
      MerchantSubjectAccVO mertchBankSubject = new MerchantSubjectAccVO();
      SubjectVO subjectVO = this.accountingDAO.queryBankAccount(this.tranInfoVO.getChannelCode());
      dividend.setSubSubjectCode(subjectVO.getSubjectCode());
      dividend.setLoanFlag(DzConstants.borrowOrLoanFlag.LOAN_FLAG.value());
      dividend.setAmount(this.tranInfoVO.getPaymentAmount());
      dividend.setTradeNo(this.tranInfoVO.getTradeNo());
      dividend.setMerchantCode(this.platMerchantCode);
      dividend.setMerchantCode1(this.cardNo);
      dividend.setAccountingDate(this.accountingDate);
      
      mertchBankSubject.setAcctBal(BigDecimalUtil.sub(BigDecimal.valueOf(0L), dividend.getAmount()));
      mertchBankSubject.setMerchantCode(this.platMerchantCode);
      mertchBankSubject.setSubSubjectCode(dividend.getSubSubjectCode());
      
      this.merchAccountDividendList.add(dividend);
      this.merchantSubjectList.add(mertchBankSubject);
      

      MerchAccountDividendVO preIncomeDividend = new MerchAccountDividendVO();
      MerchantSubjectAccVO preIncomeSubject = new MerchantSubjectAccVO();
      
      AccountingRuleVO preIncomeRule = this.accountingDAO.queryAssetsAccountRuleByServiceNo(this.tranInfoVO.getServiceNo(), DzConstants.subjectType.LIABILITIES
        .value(), DzConstants.balType.REAL_TIME.value());
      preIncomeDividend.setSubSubjectCode(preIncomeRule.getSubSubjectCode());
      preIncomeDividend.setSubjectCode(preIncomeRule.getSubjectCode());
      preIncomeDividend.setLoanFlag(DzConstants.borrowOrLoanFlag.BORROW_FLAG.value());
      preIncomeDividend.setAmount(this.tranInfoVO.getPaymentAmount());
      preIncomeDividend.setTradeNo(this.tranInfoVO.getTradeNo());
      preIncomeDividend.setMerchantCode(this.platMerchantCode);
      preIncomeDividend.setMerchantCode1(this.cardNo);
      preIncomeDividend.setAccountingDate(this.accountingDate);
      
      preIncomeSubject.setAcctBal(BigDecimalUtil.sub(BigDecimal.valueOf(0L), preIncomeDividend.getAmount()));
      preIncomeSubject.setMerchantCode(this.platMerchantCode);
      preIncomeSubject.setSubSubjectCode(dividend.getSubSubjectCode());
      
      this.merchAccountDividendList.add(preIncomeDividend);
      this.merchantSubjectList.add(preIncomeSubject);
      

      this.offlineAccountDetail = new OfflineAccountDetailVO();
      
      this.offlineAccountDetail.setCardNo(this.cardNo);
      this.offlineAccountDetail.setAccountingDate(this.accountingDate);
      this.offlineAccountDetail.setTradeNo(this.tranInfoVO.getTradeNo());
      this.offlineAccountDetail.setMerchantCode(this.platMerchantCode);
      this.offlineAccountDetail.setServiceNo(this.tranInfoVO.getServiceNo());
      this.offlineAccountDetail.setPlatTime(this.platTime);
      this.offlineAccountDetail.setPaymentAmount(this.tranInfoVO.getPaymentAmount());
      this.offlineAccountDetail.setPayFlag(DzConstants.receiveOrPay.PAY.value());
    }
    catch (Exception e)
    {
      LogUtil.error("处理总账户异常", e);
      throw e;
    }
    return this;
  }
  
  public void saveAccountDividend()
    throws Exception
  {
    init().addTotalaccount();
    if (null == this.offlineAccountDetail) {
      throw new BusinessException("离线卡账户明细为空，请检查业务逻辑。");
    }
    if (CollectionUtils.isEmpty(this.merchAccountDividendList)) {
      throw new BusinessException("分录数据为空，请检查业务逻辑。");
    }
    this.merchAccountDividendList = mergeMerchAccountDividend(this.merchAccountDividendList);
    
    int[] mc = this.accountingDAO.insertMerchAccountDividend(this.merchAccountDividendList);
    judgeResult(mc, "插入运营商账户分录，参数为：" + this.merchAccountDividendList);
    if (!this.accountingDAO.insertOfflineAccountDetail(this.offlineAccountDetail)) {
      throw new BusinessException("插入离线卡账户明细条数异常，请检查业务逻辑。参数为offlineAccountDetail：" + this.offlineAccountDetail);
    }
  }
}
